home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '93 / Papers '93 / Macintosh as Internet Server ƒ / inetd / Libraries / DaemonApp / DaemonApp.cp < prev    next >
Encoding:
Text File  |  1993-04-07  |  5.7 KB  |  292 lines  |  [TEXT/MPS ]

  1.  
  2. #include "DaemonApp.h"
  3. #include "UFailure.h"
  4.  
  5. #include <Events.h>
  6. #include <GestaltEqu.h>
  7. #include <Notification.h>
  8. #include <Desk.h>
  9.  
  10. #include <String.h>
  11. #include <Strings.h>
  12.  
  13. #if qDebug
  14. #include <StdIO.h>
  15. #endif
  16.  
  17. static DaemonApp*     gDaemon = nil;
  18.  
  19. pascal void
  20. InitUDaemonApp(long stacksize)
  21. {
  22.     static FailInfo pFi;
  23.  
  24.     CatchFailures(pFi, &TopLevelFail, &pFi);
  25.     
  26.     if (stacksize) SetApplLimit(GetApplLimit() - stacksize);
  27.     FailMemError();
  28.     MaxApplZone();
  29. }
  30.  
  31. pascal void
  32. #if qDebug
  33. TopLevelFail(short e, long m, void* )
  34. #else
  35. TopLevelFail(short , long , void* )
  36. #endif
  37. {
  38.     FailInfo fi;
  39.     
  40.     if (qDebug) {
  41.         char str[255];
  42.         sprintf(str, "TopLevelFail: error = %d, message = %d\n", e, m);
  43.         DebugStr(CStr255(str));
  44.     }
  45.     
  46.     if (fi.Try()) {
  47.         if (gDaemon) delete gDaemon;
  48.         fi.Success();
  49.     }
  50.  
  51.     ExitToShell();
  52. }
  53.  
  54. DaemonApp::DaemonApp()
  55. {
  56.     fQuit                 = false;
  57.     
  58.     this->SetSleepValue(0x7FFFFFFF);
  59.     this->SetEventMask(highLevelEventMask);
  60.     this->SetMouseRgn(nil);
  61.     this->SetEndWaitTime(3600);
  62.     
  63.     gDaemon = this;
  64. }
  65.  
  66. DaemonApp::~DaemonApp()
  67. {
  68.     if (fNoteList.First()) {
  69.         if (qDebug) DebugStr("\pThere are some notes outstanding;g");
  70.         
  71.         long now = TickCount();
  72.         while (fNoteList.First() && (TickCount() < now + fEndWait))
  73.             WaitNextEvent(osMask, &fERecord, 60, nil);
  74.     }
  75.     
  76.     if (qDebug && fNoteList.First()) DebugStr("\pThere were some left");
  77. }
  78.  
  79. void
  80. DaemonApp::Initialize()
  81. {
  82.     long    aLong = 0;
  83.  
  84.     this->InitToolBox();
  85.     this->InstallAEHandlers();
  86.     
  87.     GetCurrentProcess(&fPSN);
  88.     
  89.     fA5 = SetCurrentA5();
  90. }
  91.  
  92. void
  93. DaemonApp::InitToolBox()
  94. {
  95.     /* We are NOT initializing many managers.  We're in the background, with no */
  96.     /* face, we can't use windows or dialogs or menus.  If you need to talk to the */
  97.     /* user you can post a notification, or launch an application to communicate */
  98.     /* Passing an AppleEvent in the launchapplication trap could do the */
  99.     /* communication for you. */
  100.     
  101.     /*    The technote on BOA's says to call InitGraf to use AppleEvents, who am I
  102.         to question…
  103.     */
  104.     
  105.     InitGraf(&qd.thePort);
  106. }
  107.  
  108. void
  109. DaemonApp::Run()
  110. {
  111.     while (fQuit == false) {
  112.         WaitNextEvent(fEventMask, &fERecord, fMySleep, fMouseRgn);
  113.  
  114.         switch (fERecord.what) {
  115.             case nullEvent:
  116.                 this->DoNull();
  117.                 break;
  118.                 
  119.             case kHighLevelEvent:
  120.                 this->DoHighLevel(&fERecord);
  121.                 break;
  122.         }
  123.     }
  124. }
  125.  
  126. void    
  127. DaemonApp::DoQuit()
  128. {
  129.     fQuit = true;
  130.     WakeUpProcess(&fPSN);
  131. }
  132.  
  133. void 
  134. DaemonApp::InstallAEHandlers()
  135. {
  136.     FailInfo    fi;
  137.     
  138.     if (fi.Try()) {
  139.         FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  140.                 (EventHandlerProcPtr) DoAEOpenApplication, (long) this, false));
  141.                 
  142.         FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  143.                 (EventHandlerProcPtr) DoAEOpenDocuments, (long) this, false));
  144.                 
  145.         FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  146.                 (EventHandlerProcPtr) DoAEPrintDocuments, (long) this, false));
  147.                 
  148.         FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  149.                 (EventHandlerProcPtr) DoAEQuitApplication, (long) this, false));
  150.         
  151.         fi.Success();
  152.     }
  153.     else {
  154.         if (qDebug) DebugStr("\pInstallAEHandlers failed");
  155.         fi.ReSignal();
  156.     }
  157. }
  158.  
  159. void
  160. DaemonApp::PostNotification(char* str)
  161. {
  162.     FailInfo fi;
  163.     
  164.     if (fi.Try()) {
  165.         NMRec*    theNote    = (NMRec*) NewPtrClear(sizeof(NMRec));
  166.         FailMemError();
  167.         
  168.         Ptr        string    = NewPtr(strlen(str) + 1);
  169.         FailMemError();
  170.         
  171.         BlockMove(str, string, strlen(str) + 1);
  172.         c2pstr(string);
  173.         
  174.         theNote->qType = nmType;
  175.         theNote->nmMark = 0;
  176.         theNote->nmIcon = nil;
  177.         theNote->nmSound = nil;
  178.         theNote->nmStr = (Str255) string;
  179.         theNote->nmResp = &NMResponseProc;
  180.         theNote->nmRefCon = (long) this;
  181.         
  182.         FailOSErr(NMInstall(theNote));
  183.         
  184.         NoteItem*    nu = new NoteItem(theNote);
  185.         FailNIL(nu);
  186.         fNoteList.PutOn(nu);
  187.         
  188.         fi.Success();
  189.     }
  190.     else {
  191.         if (qDebug) DebugStr("\pPostNotification failed");
  192.         fi.ReSignal();
  193.     }
  194. }
  195.  
  196. /*    The NoteItem destructor will call this routine automatically when things are    
  197.     being cleaned up. This is nice for clean up, but needs to be kept in mind
  198.     for normal removal - if we just 'delete' the object associated with the NMRec,
  199.     its destructor will come back here. This is Bad. Thats why the nmResp field
  200.     gets zeroed. We also need to set up A5 because the destructor is virtual.
  201. */
  202. pascal void
  203. NMResponseProc(NMRec* theNote)
  204. {
  205.     NoteItem*    oldItem;
  206.     DaemonApp*    daemon;
  207.     long        oldA5;
  208.  
  209.     daemon = (DaemonApp*) theNote->nmRefCon;
  210.     oldA5 = SetA5(daemon->fA5);
  211.  
  212.     NMRemove(theNote);
  213.     theNote->nmResp = nil;
  214.     
  215.     oldItem = daemon->fNoteList.GetItem(theNote);
  216.     if (oldItem) {
  217.         daemon->fNoteList.TakeOff(oldItem);
  218.         delete oldItem;
  219.     }
  220.     
  221.     DisposePtr((Ptr) theNote->nmStr);
  222.     DisposePtr((Ptr) theNote);
  223.     
  224.     SetA5(oldA5);
  225. }
  226.  
  227. NoteItem*
  228. NoteList::GetItem(NMRec* note)
  229. {
  230.     NoteItem*    it = (NoteItem*) this->First();
  231.     
  232.     while (it && (note != it->fNote))
  233.         it = (NoteItem*) it->fNext;
  234.         
  235.     return it;
  236. }
  237.  
  238. void
  239. DaemonApp::DoHighLevel(EventRecord* AERecord)
  240. {
  241.     FailInfo fi;
  242.     
  243.     if (fi.Try()) {
  244.         FailOSErr(AEProcessAppleEvent(AERecord));
  245.         fi.Success();
  246.     }
  247.     else {
  248.         if (qDebug) {
  249.             long    evtID;
  250.             long    evtClass;
  251.                         
  252.             char str[128];
  253.             
  254.             evtID = AERecord->message;
  255.             evtClass = *((long*) &AERecord->where);
  256.             
  257.             sprintf(str, "DoHighLevel failed: class = %p, id = %p, err = %d",
  258.                         evtClass, evtID, fi.error);
  259.             
  260.             DebugStr(CStr255(str));
  261.         }
  262.         
  263.         fi.ReSignal();
  264.     }
  265. }
  266.  
  267. pascal OSErr 
  268. DoAEOpenApplication(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
  269. {
  270.     return noErr;
  271. }
  272.  
  273. pascal OSErr 
  274. DoAEOpenDocuments(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
  275. {
  276.     return errAEEventNotHandled;
  277. }
  278.  
  279. pascal OSErr 
  280. DoAEPrintDocuments(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
  281. {
  282.     return errAEEventNotHandled;
  283. }
  284.  
  285. pascal OSErr 
  286. DoAEQuitApplication(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long refIn)
  287. {
  288.     ((DaemonApp*) refIn)->DoQuit();
  289.  
  290.     return noErr;
  291. }
  292.